package gw.com.android.ui.trade;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;

import com.gwtsz.android.rxbus.RxBus;
import com.gwtsz.gts2.hx.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import gw.com.android.app.AppContances;
import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigType;
import gw.com.android.model.ConfigUtil;
import gw.com.android.model.DataManager;
import gw.com.android.presenter.TradePresenter;
import gw.com.android.terminal.AppTerminal;
import gw.com.android.terminal.GTSDataListener;
import gw.com.android.ui.dialog.OrderOutTimeDialog;
import gw.com.android.ui.dialog.PopupConfirmDialog;
import gw.com.android.ui.quote2.QuoteChartConfig;
import gw.com.android.utils.PackStatis;
import gw.com.jni.library.terminal.GTSConst;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import www.com.library.app.Logger;
import www.com.library.model.DataItemDetail;
import www.com.library.model.DataItemResult;
import www.com.library.util.DoubleConverter;
import www.com.library.util.JsonUtil;
import www.com.library.util.StringFormatter;

/**
 * 开仓弹窗业务处理
 *
 * @author jett
 * @since 2018-04-16.
 */
public class OrderOpenPresenter {

    private final String TAG = "OrderOpenPresenter";

    private int mUiCode;
    private List<Integer> mCodesRange;

    private final Activity mContext;
    private final OrderOpenDialog dialog;
    private final TradePresenter tradePresenter;

    private List<String> quickLots;
    private DataItemDetail mTickModel;              // 报价对象
    private DataItemDetail mSymbolModel = new DataItemDetail(); //产品对象
    private TradeRangeModel mRangeModel = new TradeRangeModel(); //止损止盈范围值
    private CompositeDisposable cds;
    private int mSequence;
    private DataItemDetail mResult = new DataItemDetail();

    OrderOpenPresenter(OrderOpenDialog dialog, Activity context, int uiCode, int... uiCodesRange) {
        Logger.i(TAG, "construct");
        this.dialog = dialog;
        this.mContext = context;
        this.mUiCode = uiCode;
        if (uiCodesRange != null && uiCodesRange.length > 0) {
            mCodesRange = new ArrayList<>();
            for (int code : uiCodesRange) {
                mCodesRange.add(code);
            }
        }
        tradePresenter = new TradePresenter(mUiCode);
        registerRxBus();
    }

    public void initData() {
        AppTerminal.instance().sendQuoteSubscribe(DataManager.instance().getQuoteSubscribeCode(mUiCode));
        DataItemDetail tickModel = DataManager.instance().getTickModel(mUiCode);
        toggleProduct(tickModel);
    }

    private void toggleProduct(DataItemDetail tickModel) {
        Logger.i(TAG, "start load quote");
        if (tickModel == null) {
            return;
        }
        this.mTickModel = tickModel;
        updateSymbolModel();
        updateRangeModel();

        String mProductName = DataManager.instance().getPrdName(mTickModel);
        String mCurLot = GTConfig.instance().getProductOrderLot(mUiCode, mSymbolModel.getString(GTSConst.JSON_KEY_DEFAULTOT));
        String mCurRange = GTConfig.instance().getProductRange(mUiCode, mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
        dialog.refreshProductInfo(mProductName, mCodesRange != null && mCodesRange.size() == 1);
        dialog.refreshMarketPriceValue(mRangeModel.defalutPrice);

        double minLot = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMIN));
        double maxLot = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX));
        double LotStep = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESSTEP));
        dialog.refreshLot(minLot, maxLot, LotStep, mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX));

        quickLots = OrderLotHelper.getRecommendLots(mUiCode, (float) maxLot);
        dialog.refreshQuickLots(mCurLot, quickLots);
        dialog.cancelQuickLotSelected(null);

        int maxOffset = (int) DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
        int defOffset = maxOffset;
        if (!TextUtils.isEmpty(mCurRange)) {
            try {
                defOffset = Integer.parseInt(mCurRange);
            } catch (NumberFormatException ignore) {
            }
        }
        dialog.refreshOffset(maxOffset, defOffset);

        dialog.refreshStopLossGain(mRangeModel);
        dialog.clearStopLossGain();

        dialog.refreshBail(getBail(DoubleConverter.toDoubleData(mCurLot)));
        dialog.refreshFund(getBalance());

        Logger.i(TAG, "refresh product info");
    }

    public void onExpandDialog() {
        String mCurRange = GTConfig.instance().getProductRange(mUiCode, mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
        int maxOffset = (int) DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
        int defOffset = maxOffset;
        if (!TextUtils.isEmpty(mCurRange)) {
            try {
                defOffset = Integer.parseInt(mCurRange);
            } catch (NumberFormatException ignore) {
            }
        }
        dialog.refreshOffset(maxOffset, defOffset);

        dialog.refreshStopLossGain(mRangeModel);
        dialog.clearStopLossGain();
    }

    /**
     * 切换产品
     */
    public void changeProduct(int uiCode) {
        this.mUiCode = uiCode;
        tradePresenter.setMarginLevel(mUiCode);
        initData();
    }

    /**
     * 获取本次所有可交易的产品
     */
    public List<DataItemDetail> getProductRange() {
        DataItemResult mTickList = DataManager.instance().getAllTradeTickList();
        int count = mTickList.getDataCount();
        if (count <= 0) {
            return null;
        }
        List<DataItemDetail> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            DataItemDetail item = mTickList.getItem(i);
            if (item == null) {
                continue;
            }
            int code = item.getInt(GTSConst.JSON_KEY_CODEID);
            if (mCodesRange == null || mCodesRange.contains(code)) {
                list.add(item);
            }
        }
        return list;
    }

    /**
     * 卖出 买入 方向的切换
     */
    public void toggleOrderDir() {
        updateRangeModel();
        int orderType = dialog.getOrderType();
        if (orderType != AppContances.ORDER_TYPE_MARKET_TYPE) {
            dialog.refreshMarketPrice(mRangeModel);
            dialog.refreshMarketPriceValue(mRangeModel.defalutPrice);
        }
        dialog.refreshStopLossGain(mRangeModel);
        dialog.clearStopLossGain();
        dialog.refreshBail(getBail());
    }

    /**
     * 市价、限价、停损 的切换
     */
    public void toggleOrderType() {
        int orderType = dialog.getOrderType();
        if (orderType != AppContances.ORDER_TYPE_MARKET_TYPE) {
            updateRangeModel();
            dialog.refreshMarketPrice(mRangeModel);
            dialog.refreshMarketPriceValue(mRangeModel.defalutPrice);
            double minLot = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMIN));
            double maxLot = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX));
            double LotStep = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESSTEP));
            dialog.refreshLot(minLot, maxLot, LotStep, mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX));
        }
    }

    public void onMarketPriceChanged(String price) {
        int orderType = dialog.getOrderType();
        if (orderType != AppContances.ORDER_TYPE_MARKET_TYPE) {
            TradeBusiness.calPendingLossAndWin(mTickModel, mSymbolModel, mRangeModel, price, dialog.getOrderDir(), orderType);
            dialog.refreshStopLossGain(mRangeModel);
            dialog.refreshStopLossHint();
            dialog.refreshStopGainHint();
        }
    }

    public String getQuickLot(int index) {
        if (index >= 0 && index < quickLots.size()) {
            return quickLots.get(index);
        }
        return "0.50";
    }

    public void togglePriceOrPoint() {
        dialog.refreshStopLossGain(mRangeModel);
    }

    /**
     * 点数转成价格
     */
    public String changePointToPrice(String point, boolean loss) {
        if (loss) {
            return TradeBusiness.lossPointToPrice(point, mRangeModel);
        } else {
            return TradeBusiness.profitPointToPrice(point, mRangeModel);
        }
    }

    /**
     * 价格转成点数
     */
    public String changePriceToPoint(String price, boolean loss) {
        if (loss) {
            return TradeBusiness.lossPriceToPoint(price, mRangeModel);
        } else {
            return TradeBusiness.profitPriceToPoint(price, mRangeModel);
        }
    }

    public String getBail() {
        double lot = dialog.getLot();
        return getBail(lot);
    }

    private String getBail(double lot) {
        return tradePresenter.calLevelMargin(lot, DoubleConverter.toFloatData(mSymbolModel.getString(GTSConst.JSON_KEY_MARGININITIAL)), dialog.getOrderDir(), true);
    }

    /**
     * 获取格式化的可用资金
     */
    private String getBalance() {
        String amount = DataManager.instance().mAccount.getString(GTSConst.JSON_KEY_AVAILABLE);
        try {
            double balance = Double.valueOf(amount);
            return NumberFormat.getCurrencyInstance(Locale.US).format(balance);
        } catch (Throwable t) {
            return "$" + amount;
        }
    }

    public int getUiCode() {
        return mUiCode;
    }

    public String getProductName() {
        return DataManager.instance().getPrdName(mTickModel);
    }

    /**
     * 刷新产品数据对象
     */
    private void updateSymbolModel() {
        try {
            String jsonStr = AppTerminal.instance().getTradeParamModel(mUiCode);
            if (JsonUtil.isJsonData(jsonStr)) {
                JSONObject mArray = new JSONObject(jsonStr);
                mSymbolModel.clear();
                JsonUtil.toDataItemDetail(mSymbolModel, mArray);
            }
        } catch (JSONException e) {
            Logger.e(e);
        }
    }

    /**
     * 刷新范围对象
     */
    private void updateRangeModel() {
        if (dialog.getOrderType() == AppContances.ORDER_TYPE_MARKET_TYPE) {
            TradeBusiness.calLossAndWin(mTickModel, mSymbolModel, mRangeModel, dialog.getOrderDir());
        } else {
            TradeBusiness.calPendingLossAndWin(mTickModel, mSymbolModel, mRangeModel, dialog.getPrice(), dialog.getOrderDir(), dialog.getOrderType());
        }
    }

    public CharSequence buildPriceHint(double price) {
        String text = mContext.getResources().getString(R.string.order_stop_price_range);
        String range = mRangeModel.minRangePrice + "-" + mRangeModel.maxRangePrice;
        text = String.format(Locale.getDefault(), text, range);
        if (price < DoubleConverter.toDoubleData(mRangeModel.minRangePrice) || price > DoubleConverter.toDoubleData(mRangeModel.maxRangePrice)) {
            SpannableString ss = new SpannableString(text);
            ForegroundColorSpan span = new ForegroundColorSpan(0xFFFF3232);
            int start = text.indexOf(range);
            ss.setSpan(span, start, start + range.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            return ss;
        }
        return text;
    }

    public CharSequence buildQuantityHint(double quantity) {
        String min = mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMIN);
        String max = mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX);
        double minLot = DoubleConverter.toDoubleData(min);
        double maxLot = DoubleConverter.toDoubleData(max);
        String text = mContext.getResources().getString(R.string.order_quantity_limit);
        String range = min + "-" + max;
        text = String.format(Locale.getDefault(), text, range);
        if (quantity < minLot || quantity > maxLot) {
            SpannableString ss = new SpannableString(text);
            ForegroundColorSpan span = new ForegroundColorSpan(0xFFFF3232);
            int start = text.indexOf(range);
            ss.setSpan(span, start, start + range.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            return ss;
        }
        return text;
    }

    public boolean isQuantityOutRange(double quantity) {
        String min = mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMIN);
        String max = mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX);
        double minLot = DoubleConverter.toDoubleData(min);
        double maxLot = DoubleConverter.toDoubleData(max);
        return quantity < minLot || quantity > maxLot;
    }

    public CharSequence buildStopLossHint(double value, boolean isPoint, boolean hasSet) {
        String text;
        String range;
        boolean isOutRange;
        if (isPoint) {
            text = mContext.getResources().getString(R.string.order_stop_point_range);
            range = mRangeModel.minPips + "-" + mRangeModel.maxPips;
            isOutRange = value < DoubleConverter.toDoubleData(mRangeModel.minPips) || value > DoubleConverter.toDoubleData(mRangeModel.maxPips);
        } else {
            text = mContext.getResources().getString(R.string.order_stop_price_range);
            range = mRangeModel.minRangeLoss + "-" + mRangeModel.maxRangeLoss;
            isOutRange = value < DoubleConverter.toDoubleData(mRangeModel.minRangeLoss) || value > DoubleConverter.toDoubleData(mRangeModel.maxRangeLoss);
        }
        text = String.format(Locale.getDefault(), text, range);
        if (hasSet && isOutRange) {
            SpannableString ss = new SpannableString(text);
            ForegroundColorSpan span = new ForegroundColorSpan(0xFFFF3232);
            int start = text.indexOf(range);
            ss.setSpan(span, start, start + range.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            return ss;
        }
        return text;
    }

    public CharSequence buildStopGainHint(double value, boolean isPoint, boolean hasSet) {
        String text;
        String range;
        boolean isOutRange;
        if (isPoint) {
            text = mContext.getResources().getString(R.string.order_stop_point_range);
            range = mRangeModel.minPips + "-" + mRangeModel.maxPips;
            isOutRange = value < DoubleConverter.toDoubleData(mRangeModel.minPips) || value > DoubleConverter.toDoubleData(mRangeModel.maxPips);
        } else {
            text = mContext.getResources().getString(R.string.order_stop_price_range);
            range = mRangeModel.minRangeWin + "-" + mRangeModel.maxRangeWin;
            isOutRange = value < DoubleConverter.toDoubleData(mRangeModel.minRangeWin) || value > DoubleConverter.toDoubleData(mRangeModel.maxRangeWin);
        }
        text = String.format(Locale.getDefault(), text, range);
        if (hasSet && isOutRange) {
            SpannableString ss = new SpannableString(text);
            ForegroundColorSpan span = new ForegroundColorSpan(0xFFFF3232);
            int start = text.indexOf(range);
            ss.setSpan(span, start, start + range.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            return ss;
        }
        return text;
    }

    public boolean validateMarketPrice(String price) {
        if (dialog.getOrderType() == AppContances.ORDER_TYPE_MARKET_TYPE) {
            return true;
        }
        String msg = TradeBusiness.getApplyPriceErrorMsg(mRangeModel.minRangePrice, mRangeModel.maxRangePrice, price);
        return TextUtils.isEmpty(msg);
    }

    public boolean validateLot(String lot) {
        String msg = TradeBusiness.getLotErrorMsg(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMIN),
                mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX), mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESSTEP), lot);
        return TextUtils.isEmpty(msg);
    }

    public boolean validateStopLoss(String value, boolean isPoint) {
        String msg;
        if (isPoint) {
            msg = TradeBusiness.getLossPointErrorMsg(mRangeModel.minPips, mRangeModel.maxPips, value);
        } else {
            msg = TradeBusiness.getLossPriceErrorMsg(mRangeModel.minRangeLoss, mRangeModel.maxRangeLoss, value);
        }
        return TextUtils.isEmpty(msg);
    }

    public boolean validateStopGain(String value, boolean isPoint) {
        String msg;
        if (isPoint) {
            msg = TradeBusiness.getWinPointErrorMsg(mRangeModel.minPips, mRangeModel.maxPips, value);
        } else {
            msg = TradeBusiness.getWinPriceErrorMsg(mRangeModel.minRangeWin, mRangeModel.maxRangeWin, value);
        }
        return TextUtils.isEmpty(msg);
    }

    public boolean validateServer() {
        return TradeBusiness.PreOrderCheck(mContext, mTickModel.getInt(GTSConst.JSON_KEY_ZONE), mTickModel.getInt(GTSConst.JSON_KEY_TRADESTATE), true);
    }

    /**
     * 提交下单确认咯
     */
    public void submit(int orderDir, int orderType, String price, String lot, int offset, int expireType, String stopLoss, String stopGain) {
        if (offset < 0) {
            offset = (int) DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
        }
        int cmd;
        if (orderType == AppContances.ORDER_TYPE_MARKET_TYPE) {
            cmd = AppContances.ORDER_TYPE_MARKET;
        } else {
            cmd = AppContances.ORDER_TYPE_APPLY;
        }

        lot = DoubleConverter.toStringData(lot, 2);

        mSequence = GTSDataListener.curSeq++;
        GTSDataListener.instance().addSeqList(mSequence + "", cmd + "");

        Logger.i(TAG, "submit .. cmd = " + cmd + " lot = " + lot + " mSequence = " + mSequence);
        JSONObject jsonData = new JSONObject();
        try {
            jsonData.put(GTSConst.JSON_KEY_CODEID, mUiCode);
            jsonData.put(GTSConst.JSON_KEY_DIRECTION, orderDir);
            if (orderType == AppContances.ORDER_TYPE_MARKET_TYPE) {
                if (orderDir == AppContances.TRADE_TYPE_BUY) {
                    jsonData.put(GTSConst.JSON_KEY_ORDERPRICE, mTickModel.getString(GTSConst.JSON_KEY_BUYPRICE));
                } else {
                    jsonData.put(GTSConst.JSON_KEY_ORDERPRICE, mTickModel.getString(GTSConst.JSON_KEY_SELLPRICE));
                }
                jsonData.put(GTSConst.JSON_KEY_EXPIRETYPE, AppContances.VALID_TYPE_WEEK);
                jsonData.put(GTSConst.JSON_KEY_RANGE, String.valueOf(offset));
            } else {
                jsonData.put(GTSConst.JSON_KEY_ORDERPRICE, price);
                jsonData.put(GTSConst.JSON_KEY_EXPIRETYPE, expireType);
                jsonData.put(GTSConst.JSON_KEY_RANGE, mSymbolModel.getString(GTSConst.JSON_KEY_RANGE));
            }
            jsonData.put(GTSConst.JSON_KEY_VOLUME, lot);

            jsonData.put(GTSConst.JSON_KEY_ORDERTYPE, orderType);
            jsonData.put(GTSConst.JSON_KEY_USEDIP, 0);
            jsonData.put(GTSConst.JSON_KEY_STOPLOSS, stopLoss);
            jsonData.put(GTSConst.JSON_KEY_STOPPROFIT, stopGain);
            jsonData.put(GTSConst.JSON_KEY_TRADE_SEQ, mSequence);
        } catch (JSONException e) {
            Logger.e(e);
        }

        mResult.clear();
        mResult.setStringValue("mSymbol", DataManager.instance().getPrdName(mTickModel));
        mResult.setIntValue("mPrdCode", mUiCode);
        mResult.setIntValue("mTradeDir", orderDir);
        mResult.setIntValue("mTradeType", orderType);
        mResult.setStringValue("mCurLot", lot);
        if (orderType == AppContances.ORDER_TYPE_MARKET_TYPE) {
            mResult.setStringValue("mCurrentTag", AppContances.TAB_ID_CREATE_ORDER);
            mResult.setIntValue("rangePrice", offset);
        } else {
            mResult.setStringValue("mCurrentTag", AppContances.TAB_ID_PENDING_ORDER);
            mResult.setStringValue("mPrice", price);
            if (!DoubleConverter.isZero(DoubleConverter.toFloatData(stopLoss))) {
                mResult.setStringValue("mLoss", stopLoss);
            } else {
                mResult.setStringValue("mLoss", "");
            }
            if (!DoubleConverter.isZero(DoubleConverter.toFloatData(stopGain))) {
                mResult.setStringValue("mWin", stopGain);
            } else {
                mResult.setStringValue("mWin", "");
            }
        }
        Logger.i(TAG, "submit json = " + jsonData.toString());
        Logger.i(TAG, "submit mResult = " + mResult.toJsonString());
        int result = AppTerminal.instance().reqOrder(cmd, jsonData.toString());
        if (result != 0) {
            dialog.dismiss();
            PopupConfirmDialog.NotifyPrompt(mContext, ConfigUtil.instance().mErrorConfigObject.optString(ConfigType.SERVER_ERROR_1016));
        }
    }

    /**
     * 下单 成功
     */
    private void notifySuccess(int notifyId, int orderId, DataItemDetail model) {
        if (mSequence == notifyId) {
            if (null != model) {
                mResult.setIntValue("mOrderID", orderId);
                if (mResult.getInt("mTradeType") == AppContances.ORDER_TYPE_MARKET_TYPE){
                    mResult.setStringValue("mPrice",model.getString(GTSConst.JSON_KEY_OPENPRICE));
                }else{
                    mResult.setStringValue("mPrice", model.getString(GTSConst.JSON_KEY_ORDERPRICE));
                }
                mResult.setIntValue("mType",model.getInt(GTSConst.JSON_KEY_ORDERTYPE));
                mResult.setStringValue("mTime", StringFormatter.instance().secToDateTime(model.getInt(GTSConst.JSON_KEY_TIME)));
                if (!DoubleConverter.isZero(DoubleConverter.toFloatData(model.getString(GTSConst.JSON_KEY_STOPLOSS)))) {
                    mResult.setStringValue("mLoss", model.getString(GTSConst.JSON_KEY_STOPLOSS));
                } else {
                    mResult.setStringValue("mLoss", "");
                }
                if (!DoubleConverter.isZero(DoubleConverter.toFloatData(model.getString(GTSConst.JSON_KEY_STOPPROFIT)))) {
                    mResult.setStringValue("mWin", model.getString(GTSConst.JSON_KEY_STOPPROFIT));
                } else {
                    mResult.setStringValue("mWin", "");
                }
                GTConfig.instance().saveProductOrderLot(mResult.getInt("mPrdCode"), mResult.getString("mCurLot"));
                OrderLotHelper.saveLot(mResult.getInt("mPrdCode"), mResult.getString("mCurLot"));
                int mTradeType = mResult.getInt("mTradeType");
                if (mTradeType == AppContances.ORDER_TYPE_MARKET_TYPE) {
                    GTConfig.instance().saveProductOrderRange(mResult.getInt("mPrdCode"), mResult.getString("rangePrice"));
                }
                // show success fragment
                openResultActivity(true);
                //dialog.dismiss();
                GTConfig.instance().setStringValue(QuoteChartConfig.LAST_SUCCESS_ORDER, String.valueOf(model.getInt(GTSConst.JSON_KEY_CODEID)));
                PackStatis.getToService("Buy", "Trade", null, dialog.getOrderDir() == AppContances.TRADE_TYPE_BUY ? "1" : "0");
            }
        }
    }

    /**
     * 下单失败
     */
    private void notifyFailed(int notifyId, int resultCode) {
        if (mSequence == notifyId && resultCode != 0) {
            if (resultCode == 1) {
                mResult.setIntValue("failCode", DoubleConverter.toIntData(ConfigType.SERVER_ERROR_1016));
            } else {
                mResult.setIntValue("failCode", resultCode);
            }
            // show order failed fragment
            openResultActivity(false);
            dialog.dismiss();
        }
    }

    private void openResultActivity(boolean isSuccess) {
        Intent intent = new Intent(mContext, OrderResultActivity.class);
        intent.putExtra("isSuccess", isSuccess);
        intent.putExtra("mDetail", mResult);
        mContext.startActivity(intent);
    }

    private void notifyTimeout(Bundle bundleFail) {
        //确保是这次的下单操作结果
        if (mSequence == bundleFail.getInt("iNotification")) {
            dialog.dismiss();
            if (!GTConfig.instance().mHasKickOut) {
                OrderOutTimeDialog.showOrderOutTimeDialog(mContext, false);
            }
        }
    }

    public void registerRxBus() {
        cds = new CompositeDisposable();
        Disposable quoteAllRegister = RxBus.getInstance().registertoObservableSticky(GTSConst.REPLY_SYMBOL_ALLLIST + "", Bundle.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bundle>() {
                    @Override
                    public void accept(@NonNull Bundle bundle) {
                        //Logger.i(TAG, "REPLY_SYMBOL_ALLLIST ");
                        onSymbolUpdateNotify();
                        DataItemDetail model = DataManager.instance().getTickModel(mUiCode);
                        onSymbolNotify(model);
                    }
                });
        cds.add(quoteAllRegister);

        Disposable quoteUpdateRegister = RxBus.getInstance().register(GTSConst.REPLY_SYMBOL_UPDATE + "", DataItemDetail.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<DataItemDetail>() {
                    @Override
                    public void accept(@NonNull DataItemDetail model) {
                        //Logger.i(TAG, "REPLY_SYMBOL_UPDATE ");
                        if (model.getInt(GTSConst.JSON_KEY_CODEID) == mUiCode) {
                            // Logger.i(TAG, "REPLY_SYMBOL_UPDATE onSymbolUpdateNotify");
                            onSymbolUpdateNotify();
                        }
                        if (model.getInt(GTSConst.JSON_KEY_CODEID) == mUiCode || GTSConst.CNY_CODE == model.getInt(GTSConst.JSON_KEY_CODEID)) {
                            //Logger.i(TAG, "REPLY_SYMBOL_UPDATE onSymbolNotify");
                            onSymbolNotify(model);
                        }
                    }
                });
        cds.add(quoteUpdateRegister);

        Disposable quoteTickRegister = RxBus.getInstance().register(GTSConst.REPLY_SYMBOL_TICK_UPDATE + "", DataItemDetail.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<DataItemDetail>() {

                    @Override
                    public void accept(@NonNull DataItemDetail model) {
                        //Logger.i(TAG, "REPLY_SYMBOL_TICK_UPDATE ");
                        if (model.getInt(GTSConst.JSON_KEY_CODEID) == mUiCode || GTSConst.CNY_CODE == model.getInt(GTSConst.JSON_KEY_CODEID)) {
                            //Logger.i(TAG, "REPLY_SYMBOL_TICK_UPDATE onSymbolNotify");
                            onSymbolNotify(model);
                        }
                    }
                });
        cds.add(quoteTickRegister);

        Disposable marginRegister = RxBus.getInstance().register(GTSConst.REPLY_MARGIN_UPDATE + "", Bundle.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bundle>() {

                    @Override
                    public void accept(@NonNull Bundle bundle) {
                        if (null != bundle) {
                            tradePresenter.setMarginLevel(mUiCode);
                            dialog.refreshBail(getBail());
                        }
                    }
                });
        cds.add(marginRegister);

        Disposable positionListRegister = RxBus.getInstance().registertoObservableSticky(GTSConst.REPLY_POSTION_LIST + "", Bundle.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bundle>() {

                    @Override
                    public void accept(@NonNull Bundle bundle) {
                        dialog.refreshBail(getBail());
                    }
                });
        cds.add(positionListRegister);

        Disposable successRegister = RxBus.getInstance().register(GTSConst.REPLY_ORDER_SUCCESS + "", Bundle.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bundle>() {

                    @Override
                    public void accept(@NonNull Bundle bundleSuc) throws Exception {
                        if (null != bundleSuc) {
                            notifySuccess(bundleSuc.getInt("iNotification"), bundleSuc.getInt("iValue"), (DataItemDetail) bundleSuc.getParcelable("model"));
                        }
                    }
                });
        cds.add(successRegister);

        Disposable failRegister = RxBus.getInstance().register(GTSConst.REPLY_ORDER_FAILED + "", Bundle.class).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Bundle>() {

                    @Override
                    public void accept(@NonNull Bundle bundleFail) throws Exception {
                        if (null != bundleFail) {
                            if (bundleFail.getInt("iValue") != AppContances.HANDLER_ORDER_TIME_OUT) {
                                notifyFailed(bundleFail.getInt("iNotification"), bundleFail.getInt("iValue"));
                            } else {
                                notifyTimeout(bundleFail);
                            }
                        }
                    }
                });
        cds.add(failRegister);
        // dialog 事件监听，交易完成后的activity ，可选择关闭dialog 或者 继续交易
        Disposable dialogRegister = RxBus.getInstance().register("order_open_dialog_listener", String.class).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String replay) {
                if ("close".equals(replay)) {
                    dialog.dismiss();
                } else if ("keep".equals(replay)) {
                    dialog.keepTrade();
                    double maxLot = DoubleConverter.toDoubleData(mSymbolModel.getString(GTSConst.JSON_KEY_VOLUMESMAX));
                    quickLots = OrderLotHelper.getRecommendLots(mUiCode, (float) maxLot);
                    String mCurLot = GTConfig.instance().getProductOrderLot(mUiCode, mSymbolModel.getString(GTSConst.JSON_KEY_DEFAULTOT));
                    dialog.refreshQuickLots(mCurLot, quickLots);
                }
            }
        });
        cds.add(dialogRegister);
    }

    private void onSymbolUpdateNotify() {
        updateSymbolModel();
        dialog.refreshBail(getBail());
    }

    private void onSymbolNotify(DataItemDetail tickModel) {
        if (tickModel == null) {
            return;
        }
        if (mUiCode == tickModel.getInt(GTSConst.JSON_KEY_CODEID)) {
            this.mTickModel = tickModel;
            updateRangeModel();

            String salePrice = mTickModel.getString(GTSConst.JSON_KEY_SELLPRICE);
            int saleState = mTickModel.getInt(GTSConst.JSON_KEY_SELLPRICESTATE);
            int saleArrow = mTickModel.getInt(GTSConst.JSON_KEY_SELLPRICEARRAW);

            String buyPrice = mTickModel.getString(GTSConst.JSON_KEY_BUYPRICE);
            int buyState = mTickModel.getInt(GTSConst.JSON_KEY_BUYPRICESTATE);
            int buyArrow = mTickModel.getInt(GTSConst.JSON_KEY_BUYPRICEARRAW);
            dialog.refreshQuotePrice(salePrice, saleState, saleArrow, buyPrice, buyState, buyArrow);
            String mSpread = mTickModel.getString(GTSConst.JSON_KEY_DIFF);
            dialog.refreshSpread(mSpread);
            dialog.refreshMarketPrice(mRangeModel);
            dialog.refreshPriceHint();
            dialog.refreshStopLossGain(mRangeModel);
            dialog.refreshStopLossHint();
            dialog.refreshStopGainHint();
        } else {
            dialog.refreshBail(getBail());
        }
    }

    public void onDestroy() {
        if (cds != null) {
            cds.clear();
        }
    }

}
